// 混合数据API适配器
import api from './index'; // 导入原有API实例
import { mockData } from './mockData.fixed'; // 使用修复后的备用数据
import Logger from '../utils/logger';

// 导入扩展的备用数据，确保为缺失路径提供备用数据
import './mockDataAdditions'; // 导入额外的备用数据

/**
 * API基础配置
 */
const HybridConfig = {  // 是否启用混合数据模式（默认启用）
  enableHybridMode: true,
  
  // 是否在API请求失败时使用备用数据（一定要启用，以处理CORS等问题）
  fallbackToMockOnFailure: true,
  
  // 是否显示备用数据标记
  showMockDataIndicator: true,
    // API请求超时时间（毫秒）- 较短的超时确保更快地回退到备用数据
  requestTimeout: 5000,
  
  // 最大重试次数
  maxRetries: 1,
  
  // 是否在控制台打印详细日志
  verbose: true
};

/**
 * 获取是否使用备用数据的全局设置
 * @returns {boolean} - 是否使用备用数据
 */
export const getUseMockData = () => {
  const setting = localStorage.getItem('useMockData');
  return setting === null ? true : setting === 'true';
};

/**
 * 设置是否使用备用数据
 * @param {boolean} value - 是否使用备用数据
 */
export const setUseMockData = (value) => {
  localStorage.setItem('useMockData', value.toString());
};

/**
 * 混合数据API请求
 * 首先向后端发送请求验证授权，然后返回本地模拟数据
 * @param {string} url - API路径
 * @param {Object} options - 请求选项
 * @returns {Promise} - 包含数据的Promise
 */
export const hybridRequest = async (url, options = {}) => {
  const method = options.method || 'GET';
  const params = options.params || {};
  const data = options.data;
  
  // 处理URL路径，确保以/开头
  const path = url.startsWith('/') ? url : `/${url}`;
  
  // 如果不启用混合模式，直接使用原始API
  if (!HybridConfig.enableHybridMode || !getUseMockData()) {
    try {
      if (method.toUpperCase() === 'GET') {
        return await api.get(path, { params });
      } else if (method.toUpperCase() === 'POST') {
        return await api.post(path, data);
      } else if (method.toUpperCase() === 'PUT') {
        return await api.put(path, data);
      } else if (method.toUpperCase() === 'DELETE') {
        return await api.delete(path, { params });
      } else if (method.toUpperCase() === 'PATCH') {
        return await api.patch(path, data);
      }
    } catch (error) {
      Logger.error(`API请求失败: ${path}`, error);
      throw error;
    }
  }
    // 混合模式处理
  try {
    Logger.info(`混合模式API请求: ${method} ${path}`);
    
    // 1. 发送实际API请求，仅验证连接和权限
    try {
      // 发送请求验证后端连接，但始终使用模拟数据
      if (method.toUpperCase() === 'GET') {
        await api.get(path, { params });
      } else if (method.toUpperCase() === 'POST') {
        await api.post(path, data);
      } else if (method.toUpperCase() === 'PUT') {
        await api.put(path, data);
      } else if (method.toUpperCase() === 'DELETE') {
        await api.delete(path, { params });
      } else if (method.toUpperCase() === 'PATCH') {
        await api.patch(path, data);
      }
      
      Logger.debug(`API连接验证成功，返回数据: ${path}`);
    } catch (error) {
      // 检查是否为CORS错误或其他连接问题
      const isCorsError = error.message && (
        error.message.includes('CORS') || 
        error.message.includes('跨域') ||
        error.message.includes('cross-origin') ||
        error.message.includes('Access-Control-Allow-Origin') ||
        (error.response && error.response.status === 0)
      );
      
      if (isCorsError) {
        Logger.warn(`跨域(CORS)请求被阻止: ${path}，使用数据`);
        Logger.debug(`CORS错误详情: ${error.message}`);
      } else if (error.response && error.response.status === 401) {
        Logger.info(`API返回401未授权: ${path}，使用数据`);      } else {
        Logger.warn(`API请求失败: ${path}，回退到数据`);
        Logger.debug(`错误详情: ${error.message}`);
      }
      
      // 如果未配置回退到备用数据，则抛出错误
      if (!HybridConfig.fallbackToMockOnFailure) {
        Logger.error(`API请求失败且未配置回退: ${path}`, error);
        throw error;
      }
    }    // 2. 获取备用数据（无论API请求成功与否都使用备用数据）
    const mockResponse = getMockData(path, params);
      // 添加详细的日志记录    Logger.backupData(`响应API请求: ${path}`, mockResponse);
    // 3. 标记数据
    if (mockResponse && HybridConfig.showMockDataIndicator) {
      mockResponse.__isMockData = true;
    }
    
    return mockResponse;
  } catch (error) {
    Logger.error(`混合API请求出错: ${path}`, error);
    throw error;
  }
};

/**
 * 获取备用数据
 * @param {string} path - API路径
 * @param {Object} params - 请求参数
 * @returns {Object} - 备用数据
 */
function getMockData(path, params = {}) {
  // 去除开头的斜杠以便匹配mockData中的键
  const cleanPath = path.startsWith('/') ? path.substring(1) : path;
  
  // 根据路径获取对应的模拟数据
  const mockDataKey = getMockDataKey(cleanPath);
  const mockDataEntry = mockData[mockDataKey];
  
  if (!mockDataEntry) {
    Logger.warn(`未找到路径的模拟数据: ${cleanPath}`);
    return { 
      success: true, 
      message: '操作成功',
      data: {}
    };
  }
  
  // 如果模拟数据是函数，则调用该函数并传入参数
  if (typeof mockDataEntry === 'function') {
    return mockDataEntry(params);
  }
  
  // 否则直接返回模拟数据
  return mockDataEntry;
}

/**
 * 根据API路径获取对应的mockData键
 * @param {string} path - API路径
 * @returns {string} - mockData中的键
 */
function getMockDataKey(path) {  // 移除参数部分
  const pathWithoutParams = path.split('?')[0];
    
  // 常见路径映射
  const pathMapping = {
    'device/list': 'deviceList',
    'device/status': 'deviceStatus',
    'data/today': 'todayData',
    'data/history': 'historyData',
    'dashboard/overview': 'dashboardOverview',
    'dashboard/stats': 'dashboardStats',
    'dashboard/alerts': 'dashboardAlerts',
    'dashboard/device-status': 'deviceStatusDashboard',
    'users': 'userList',
    'users/current': 'currentUser'
  };
  
  return pathMapping[pathWithoutParams] || pathWithoutParams;
}

/**
 * 配置混合数据API
 * @param {Object} config - 配置对象
 */
export const configureHybridApi = (config = {}) => {
  if (typeof config.enableHybridMode === 'boolean') {
    HybridConfig.enableHybridMode = config.enableHybridMode;
  }
  
  if (typeof config.fallbackToMockOnFailure === 'boolean') {
    HybridConfig.fallbackToMockOnFailure = config.fallbackToMockOnFailure;
  }
  
  if (typeof config.showMockDataIndicator === 'boolean') {
    HybridConfig.showMockDataIndicator = config.showMockDataIndicator;
  }
  
  Logger.info('混合API配置已更新', HybridConfig);
};

// 导出配置对象的只读副本
export const hybridConfig = { ...HybridConfig };

// 导出备用数据检查函数
export const isMockData = (data) => {
  return data && data.__isMockData === true;
};

// 默认导出
export default {
  hybridRequest,
  configureHybridApi,
  getUseMockData,
  setUseMockData,
  isMockData,
  config: hybridConfig
};
